package com.hj.config.security.provider;

import com.hj.config.security.token.PwdLoginToken;
import com.hj.domain.LoginUser;
import com.hj.domain.constant.HjConstant;
import com.hj.exception.ParamsException;
import com.hj.exception.em.ParamsExceptionEm;
import com.hj.util.CypherUtil;
import com.hj.util.RedisUtil;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;

import java.nio.charset.StandardCharsets;

/**
 * @Description 密码登录认证拦截
 * @author hj
 */
@Component
public class PwdLoginProvider implements AuthenticationProvider {


    private UserDetailsService userDetailsServiceImpl;

    private PasswordEncoder passwordEncoder;

    private CypherUtil cypherUtil;

    private RedisUtil redisUtil;


    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        PwdLoginToken authenticationToken = (PwdLoginToken) authentication;
        UserDetails userDetails = userDetailsServiceImpl.loadUserByUsername((String) authenticationToken.getPrincipal());
        if (null == userDetails) {
            throw new InternalAuthenticationServiceException("Unable to obtain user information");
        }

        String presentedPassword = authentication.getCredentials().toString();
        byte[] decode = Base64Utils.decodeFromString(presentedPassword);
        String decryptPwd = new String(decode, StandardCharsets.UTF_8);
        LoginUser loginUser = (LoginUser) userDetails;
        String key = cypherUtil.aesDecode(loginUser.getMobile()) + HjConstant.REDIS_SMS_CODE_KEY;
        /*String verifyCode;
        if (redisUtil.exists(key)) {
            verifyCode = redisUtil.get(key).toString();
        } else {
            throw new ParamsException(ParamsExceptionEm.VERIFY_CODE_EXPIRED);
        }
        if (StrUtil.isBlank(verifyCode) || !verifyCode.equals(authenticationToken.getVerifyCode())) {
            throw new ParamsException(ParamsExceptionEm.VERIFY_CODE_WRONG);
        }*/
        if (!passwordEncoder.matches(decryptPwd, userDetails.getPassword())) {
            System.out.println(".......");
            throw new ParamsException(ParamsExceptionEm.PWD_WRONG);
        }
        PwdLoginToken authenticationResult = new PwdLoginToken(userDetails, null, null, userDetails.getAuthorities());

        authenticationResult.setDetails(authenticationToken.getDetails());

        return authenticationResult;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return PwdLoginToken.class.isAssignableFrom(authentication);
    }


    public UserDetailsService getUserDetailsServiceImpl() {
        return userDetailsServiceImpl;
    }

    public void setUserDetailsServiceImpl(UserDetailsService userDetailsServiceImpl) {
        this.userDetailsServiceImpl = userDetailsServiceImpl;
    }

    public PasswordEncoder getPasswordEncoder() {
        return passwordEncoder;
    }

    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    public CypherUtil getCypherUtil() {
        return cypherUtil;
    }

    public void setCypherUtil(CypherUtil cypherUtil) {
        this.cypherUtil = cypherUtil;
    }

    public RedisUtil getRedisUtil() {
        return redisUtil;
    }

    public void setRedisUtil(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }


}
